﻿/*
****************************************************************************************************************
*= = 版权信息：Copyright (C) 356 - 999. Ombres Industry Empiral. All rights reserved.
*= = 文件名称：Windurb.cxx
*= = 功能描述：五色水仙从站定义主文件
*= = 编写人员：Carlyon W. Tung
****************************************************************************************************************
*/

/*
*===============================================================================================================
*= = 声明文件
*===============================================================================================================
*/

#include <cstdio>
#include <thread>

#include <Orcinus.h>

#include "Windurb.h"

/*
*===============================================================================================================
*= = 预处理声明
*===============================================================================================================
*/

#ifdef HAVE_CONFIG_H
    #include <config.h>
#endif // End of HAVE_CONFIG_H

/*
*===============================================================================================================
*= = 宏定义
*===============================================================================================================
*/

#define COPYRIGHT "Copyright (C) 356 - 999. Ombres Industry Empiral. All rights reserved."
#define WUVERSION "Windurb 1.0.1 - 365"
#define WUAUTHORS "Carlyon W. Tung    loongs@syuusui.com"

/*
*===============================================================================================================
*= = 命名空间
*===============================================================================================================
*/

using namespace std;
using namespace Windurb;

/*
*===============================================================================================================
*= = 全局变量
*===============================================================================================================
*/

static const char* tmf = "Dwarfs.csv";
static const char* tsf = "Ginkgo.csv";

static int counter = 0;
static sig_atomic_t running = 0;

/*
*===============================================================================================================
*= = 函数定义
*===============================================================================================================
*/

/*
*===============================================================================================================
*= = 函数名称：get_qds_string
*= = 功能描述：
*= = 入口参数：
*= = 出口参数：
*===============================================================================================================
*/

const char* get_qds_string(uint8_t qds, int sp)
{
    static char buffer[32] = {0};
    int length = 0;

    if (qds & IECF_IV)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'I';
            buffer[length++] = 'V';
        }
    }

    if (qds & IECF_NT)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'N';
            buffer[length++] = 'T';
        }
    }

    if (qds & IECF_SB)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'S';
            buffer[length++] = 'B';
        }
    }

    if (qds & IECF_BL)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'B';
            buffer[length++] = 'L';
        }
    }

    if (qds & IECF_IN)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'I';
            buffer[length++] = 'N';
        }
    }

    if (sp && qds & IECF_GN)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'G';
            buffer[length++] = 'N';
        }
    }

    if (!sp && qds & IECF_AV)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'A';
            buffer[length++] = 'V';
        }
    }

    if (!sp && qds & IECF_OV)
    {
        if (length)
        {
            buffer[length++] = '-';
            buffer[length++] = 'O';
            buffer[length++] = 'V';
        }
    }

    buffer[length] = 0;
    return buffer;
}

/*
*===============================================================================================================
*= = 函数名称：iec_object_listener
*= = 功能描述：
*= = 入口参数：
*= = 出口参数：void
*===============================================================================================================
*/

void iec_object_listener(uint16_t ca, uint32_t ioa, const info_object_t* data)
{
    static const char* values[] = { "IND", "OFF", "ON", "IND" };
    counter++;

    printf("%3d %03d/%d\t ", data->type, ca, ioa);
    switch (data->type)
    {
    case IECT_SINGLE:
        {
            printf("= %s %s\n", values[(data->value.int8 & 1) + 1], get_qds_string(data->qds, 1));
        }
        break;
    case IECT_DOUBLE:
        {
            printf("= %s %s\n", values[data->value.int8 & 3], get_qds_string(data->qds, 1));
        }
        break;
    case IECT_FLOAT:
        {
            printf("= %.3f %s\n", data->value.real, get_qds_string(data->qds, 0));
        }
        break;
    default:
        {
            printf("Unknown Data Type!\n");
        }
        break;
    }

    return;
}

/*
*===============================================================================================================
*= = 函数名称：windurb_sigint
*= = 功能描述：五色水仙服务器信号处理函数
*= = 入口参数：int
*= = 出口参数：void
*===============================================================================================================
*/

static void windurb_sigint(int signum)
{
    running = 0;

    iec_stop();
}

/*
*===============================================================================================================
*= = 函数名称：windurb_start
*= = 功能描述：启动五色水仙服务器
*= = 入口参数：void
*= = 出口参数：int
*===============================================================================================================
*/

static int windurb_start(void)
{
    const char* config_files[] = { tmf, tsf, NULL };

    if (iec_load_config_from_files("./Asgard", "Windurb.csv", config_files, NULL, NULL) < 0)
    {
        fprintf(stderr, "%s\n", iec_lasterror());
        return -1;
    }

    iec_set_event_listener(NULL);
    iec_set_object_listener(iec_object_listener);

    if (iec_start() < 0)
    {
        fprintf(stderr, "%s\n", iec_lasterror());
        iec_free();

        return -1;
    }

    return EXIT_SUCCESS;
}

/*
*===============================================================================================================
*= = 函数名称：windurb_run
*= = 功能描述：运行五色水仙服务器
*= = 入口参数：void
*= = 出口参数：int
*===============================================================================================================
*/

static int windurb_run(void)
{
    signal(SIGINT, windurb_sigint);

    std::cout << "Press Ctrl-C to exit." << std::endl;

    iec_wait();

    return EXIT_SUCCESS;
}

/*
*===============================================================================================================
*= = 函数名称：windurb_stop
*= = 功能描述：停止五色水仙服务器
*= = 入口参数：void
*= = 出口参数：void
*===============================================================================================================
*/

static void windurb_stop(void)
{
    iec_stop();
    iec_free();
}

/*
*===============================================================================================================
*= = 函数名称：main
*= = 功能描述：基本入口函数
*= = 入口参数：int、char **
*= = 出口参数：int
*===============================================================================================================
*/

int main(int argc, char *argv[])
{
    std::cout << COPYRIGHT << std::endl;
    std::cout << WUVERSION << std::endl;
    std::cout << WUAUTHORS << std::endl;

    std::cout << "Windurb - Windurb: Hello, slaver!" << std::endl;

#ifdef __INSIGHT_OS_WINDOWS__
    sockets_init();
    atexit(sockets_free);
#endif

    if (0 != windurb_start() || 0 != windurb_run())
    {
        std::cout << "Windurb - Windurb: Sorry, slaver!" << std::endl;
        return EXIT_FAILURE;
    }

    windurb_stop();

    std::cout << "Windurb - Windurb: Goodbye, slaver!" << std::endl;
    return EXIT_SUCCESS;
}


/*
****************************************************************************************************************
*= = 文件结束
****************************************************************************************************************
*/


